#include <iostream>
#include <vector>
#include <iomanip>
#include <fstream>
#include <stdlib.h>
using namespace std;

//Prototipos
void CrearMatrizT(double);
void inicializarMatrizT();
void imprimitMatrizT();
void imprimitMatrizU();
void imprimirArchivoSalida();
void productoMatrizTVectorU();

//Variables Globales
vector<double> matrizU;
vector<double> matrizT;
int sizeIni;

int main(int argc, char **argv) {
	double z;
	double var;
	int tamb;
	cout<<endl<<"\t\tIntroduzca el valor de Z (Z=C*dt/h^2):"<<endl;
	cin>>z;
	if(z>0.5){
			cout<<"ERROR! z>0.5 introduzca un valor de z diferente"<<endl;
			return 0;
	}
	cout<<endl<<"\t\tIntroduzca las condiciones iniciales de la barra -1-->Terminar"<<endl;
	cin>>var;
	while(var!=-1){
		matrizU.push_back(var);
		cin>>var;
	}
	sizeIni=matrizU.size();
	tamb=sizeIni;
	inicializarMatrizT();
	CrearMatrizT(z);
	cout<<endl<<"\t\tMatriz T"<<endl;
	imprimitMatrizT();
	productoMatrizTVectorU();
	imprimirArchivoSalida();
	system("gnuplot splot.gp");
	system("eog aux.png");

}

//Definicion de Funciones
void inicializarMatrizT(){
	for(int i=0;i<sizeIni*sizeIni;i++){
		matrizT.push_back(0);
	}
}

void CrearMatrizT(double z){
	int size=sizeIni;
	for(int i=0;i<size;i++){
		if(i==0){
			matrizT[i+1]=z;
			matrizT[i]=1-2*z;
		}
		else if(i==size-1){
			matrizT[size*size-2]=z;
			matrizT[size*size-1]=1-2*z;
		}
		else{
			matrizT[size*i+i-1]=z;
			matrizT[size*i+i]=1-2*z;
			matrizT[size*i+i+1]=z;

		}
	}
}
void imprimitMatrizT(){
	for(int i=0;i<matrizT.size();i++){
				cout<<setw(5)<<setprecision(2)<<matrizT[i]<<setw(5);
				if((i+1)%sizeIni==0){
					cout<<endl;
				}
		}
}
void imprimitMatrizU(){
	for(int i=0;i<matrizU.size();i++){
				cout<<setw(5)<<setprecision(2)<<matrizU[i]<<setw(5);
				if((i+1)%sizeIni==0){
					cout<<endl;
				}
		}
}
void imprimirArchivoSalida(){
	fstream salida("salida.txt",ios::out);
	int j=0,k=0;
	for(int i=0;i<matrizU.size();i++){
					salida<<j<<" "<<k<<" "<<matrizU[i]<<endl;
					k++;
					if((i+1)%sizeIni==0){
						j++;
						k=0;
					}
			}
	salida.close();
}

void productoMatrizTVectorU(){
	double sum=0;
	int k=1,j=0,z;
	while(k<1000){
		z=matrizU.size()-sizeIni;
		for(int i=0; i<matrizT.size(); i++) {

	    		sum+=matrizT[i]*matrizU[j];
	    		j++;
	        if((i+1)%sizeIni==0){
	    	 	 matrizU.push_back(sum);
	    	 	 sum=0;
	    	 	 j=z;
	     	 }
		}
		k++;
	}
}
